package com.mars.common.util;

import com.mars.framework.config.EasyAdminConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.FastByteArrayOutputStream;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Random;

/**
 * @author mars
 * @version 1.0
 * @date 2023/10/31 22:16
 */
@Slf4j
public class ValidateCodeUtils {
    private static final Random random = new Random();
    /**
     * 宽
     */
    private final int width = 160;
    /**
     * 高
     */
    private final int height = 40;

    /**
     * 字符串类型
     */
    public static final String STRING = "string";

    /**
     * 数字类型
     */
    public static final String NUMBER = "number";

    /**
     * 字符串
     */
    private final String randomString = "abcdefghijklmnopqrstuvwxyz";
    /**
     * 随机数字
     */
    private final String randomNumber = "0123456789";


    /*
     *  获取字体
     */
    private Font getFont() {
        return new Font("Times New Roman" , Font.PLAIN, 40);
    }

    /*
     *  获取颜色
     */
    private static Color getRandomColor(int fc, int bc) {
        fc = Math.min(fc, 255);
        bc = Math.min(bc, 255);
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 12);

        return new Color(r, g, b);
    }

    /*
     *  绘制干扰线
     */
    private void drawLine(Graphics g) {
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(20);
        int yl = random.nextInt(10);
        g.drawLine(x, y, x + xl, y + yl);
    }

    /**
     * 获取随机字符
     *
     * @param num num
     * @return String
     */
    private String getRandomString(int num) {
        num = num > 0 ? num : randomString.length();
        return String.valueOf(randomString.charAt(random.nextInt(num)));
    }


    /**
     * 获取随机数字
     *
     * @param num num
     * @return String
     */
    private String getRandomNumber(int num) {
        num = num > 0 ? num : randomNumber.length();
        return String.valueOf(randomNumber.charAt(random.nextInt(num)));
    }


    /**
     * 绘制字符串
     *
     * @param g         g
     * @param randomStr randomStr
     * @param i         i
     * @return String
     */
    private String drawString(Graphics g, String randomStr, int i) {
        g.setFont(getFont());
        g.setColor(getRandomColor(108, 190));
        String rand = getRandomString(random.nextInt(randomString.length()));
        randomStr += rand;
        g.translate(random.nextInt(3), random.nextInt(6));
        g.drawString(rand, 40 * i + 10, 25);
        return randomStr;
    }


    /**
     * 绘制字符串
     *
     * @param g         g
     * @param randomStr randomStr
     * @param i         i
     * @return String
     */
    private String drawNumber(Graphics g, String randomStr, int i) {
        g.setFont(getFont());
        g.setColor(getRandomColor(108, 190));
        String rand = getRandomNumber(random.nextInt(randomNumber.length()));
        randomStr += rand;
        g.translate(random.nextInt(3), random.nextInt(6));
        g.drawString(rand, 40 * i + 10, 25);
        return randomStr;
    }


    /**
     * 生成随机图片
     *
     * @param request         request
     * @param easyAdminConfig easyAdminConfig
     * @return String
     */
    public Map<String, FastByteArrayOutputStream> getRandomCodeImage(HttpServletRequest request, EasyAdminConfig easyAdminConfig) {
        HttpSession session = request.getSession();
        // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, width, height);
        g.setColor(getRandomColor(105, 189));
        g.setFont(getFont());
        // 干扰线数量
        int lineSize = 30;
        for (int i = 0; i < lineSize; i++) {
            drawLine(g);
        }
        // 绘制随机字符
        String randomString = "";
        String captchaType = easyAdminConfig.getCaptchaType();
        // 随机产生字符的个数
        int stringNum = 4;
        for (int i = 0; i < stringNum; i++) {
            if (STRING.equals(captchaType)) {
                randomString = drawString(g, randomString, i);
            } else {
                randomString = drawNumber(g, randomString, i);
            }
        }
        log.info(randomString);
        g.dispose();
        String sessionKey = "RANDOMKEY";
        session.removeAttribute(sessionKey);
        session.setAttribute(sessionKey, randomString);
        HashMap<String, FastByteArrayOutputStream> map = new HashMap<>();
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            //  直接返回图片
            ImageIO.write(image, "jpg" , os);
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put(randomString, os);
        return map;
    }
}
